package de.bastian.hinterleitner.tools;

import java.util.ArrayList;

import net.londatiga.android.ActionItem;
import net.londatiga.android.QuickAction;
import net.londatiga.android.QuickAction.OnActionItemClickListener;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.WrapperListAdapter;

import com.agimind.widget.SlideHolder;

import de.bastian.hinterleitner.Categories;
import de.bastian.hinterleitner.Main;
import de.bastian.hinterleitner.NewEntry;
import de.bastian.hinterleitner.Overview;
import de.bastian.hinterleitner.Search;
import de.bastian.hinterleitner.Selection;
import de.bastian.hinterleitner.WhatsNewActivity;
import de.bastian.hinterleitner.XmlActivity;
import de.bastian.hinterleitner.adaptersviews.BasicAdapter;
import de.bastian.hinterleitner.adaptersviews.Diagram;
import de.hijacksoft.wyc.R;

/**
 * 
 * @author basti
 */
public abstract class WatchYourCashActivity extends WrapperActivity {

	private LinearLayout horizontalDiagramLayout;
	private SlideHolder leftNavigation;
	private Diagram diagram;
	private Button diagramButton;
	private ListView list;
	private ImageButton back;

	private static final String TAG = "WatchYourCash_WYCActivity";

	private boolean showDiagram = false;

	private LinearLayout loadingView;

	private LinearLayout navButtons;
	private String[] navs;
	private TextView headText;

	/**
	 * limit where the screen in landscape always shows diagram
	 */
	protected final int SCREEN_LIMIT = 480;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (savedInstanceState != null) {
			navs = savedInstanceState.getStringArray("navs");
			setDiagram(savedInstanceState.getBoolean("diagram"));
		}
		initLoader();
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		if (navButtons != null) {
			String[] navs = new String[navButtons.getChildCount() + 1];
			for (int i = 0; i < navButtons.getChildCount(); i++) {
				navs[i] = (((Button) navButtons.getChildAt(i)).getText()
						.toString());
			}
			navs[navButtons.getChildCount()] = headText.getText().toString();
			outState.putStringArray("navs", navs);
		}
		outState.putBoolean("diagram", isDiagramShown());
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == Constants.RESULT_KILLME)
			finish();
	}

	@Override
	protected void onDestroy() {
		notifyWidget();
		super.onDestroy();
	}

	private final void initLoader() {
		loadingView = new LinearLayout(this);
		loadingView.addView(new ProgressBar(this));
		loadingView.setVisibility(View.GONE);
		loadingView.setGravity(android.view.Gravity.CENTER);
		ViewGroup view = (ViewGroup) getWindow().getDecorView();
		view.addView(loadingView);
	}

	protected final void notifyWidget() {
		Intent widgetUpdateIntent = new Intent(this, UpdateWidgetService.class);
		startService(widgetUpdateIntent);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {

		if (back != null && navButtons != null) {
			if (navButtons.getChildCount() > 0) {
				setMenuOnButton(back, false);
			} else {
				setMenuOnButton(back, true);
			}
		}

		if ((keyCode == KeyEvent.KEYCODE_BACK) && navButtons != null) {
			if (navButtons.getChildCount() == 0) {
				finish();
				return true;
			} else {
				Button b = (Button) navButtons.getChildAt(navButtons
						.getChildCount() - 1);
				onNavEntryClicked(b);
				setNavEntry(b.getText().toString());
				return true;
			}
		} else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
			startActivityForResult(new Intent(this, Search.class),
					Constants.REQUEST_OVERVIEW);
			return true;
		} else
			return super.onKeyDown(keyCode, event);
	}

	protected final void loading(boolean b) {
		ViewGroup view = (ViewGroup) getWindow().getDecorView();
		View content = view.getChildAt(0);
		if (b) {
			content.setVisibility(View.GONE);
			loadingView.setVisibility(View.VISIBLE);
		} else {
			content.setVisibility(View.VISIBLE);
			loadingView.setVisibility(View.GONE);
		}
		if (back != null && navButtons != null) {
			if (navButtons.getChildCount() > 0) {
				setMenuOnButton(back, false);
			} else {
				setMenuOnButton(back, true);
			}
		}
	}

	protected final void initLeftNavigation(LinearLayout parent) {
		LinearLayout leftNavigation = createLeftNavigation(this);
		parent.addView(leftNavigation);
	}

	protected final void initNav(LinearLayout parent, String title) {
		LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View view = inflator.inflate(R.layout.layout_header, parent);

		headText = (TextView) view.findViewById(R.id.layout_header_txt_head);
		navButtons = (LinearLayout) view
				.findViewById(R.id.layout_header_navbuttons);

		back = (ImageButton) view.findViewById(R.id.layout_header_btn_back);

		ImageButton info = (ImageButton) view
				.findViewById(R.id.layout_header_btn_search);
		info.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				startActivity(new Intent(getApplicationContext(),
						WhatsNewActivity.class));
			}
		});

		final ImageButton options = (ImageButton) view
				.findViewById(R.id.layout_header_btn_options);
		if (hasOptionsMenu())
			options.setVisibility(View.VISIBLE);

		options.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
			@Override
			public void onCreateContextMenu(ContextMenu m, View v,
					ContextMenuInfo i) {
				onCreatePopupMenu(m);
				onMenuOpened(0, m);
				showOptions(v, m);
			}
		});

		options.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (options.showContextMenu()) {
					closeContextMenu();
				}
			}
		});

		if (navs != null) {
			for (String s : navs) {
				addNavItem(s);
			}
			navs = null;
		} else {
			addNavItem(title);
		}

		if (back != null && navButtons != null) {
			if (navButtons.getChildCount() > 0) {
				setMenuOnButton(back, false);
			} else {
				setMenuOnButton(back, true);
			}
		}
		
		initAdView();
	}

	private void setMenuOnButton(ImageButton button, final boolean hasMenu) {
		if (hasMenu) {
			back.setImageResource(R.drawable.more);
		} else {
			back.setImageResource(R.drawable.btn_back);
		}
		back.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (hasMenu) {
					toggleLeftNavigation();
				} else {
					onKeyDown(KeyEvent.KEYCODE_BACK, new KeyEvent(
							KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
				}
			}
		});
	}

	private void showOptions(View v, Menu menu) {
		initOptionsDropDown(menu).show(v);
	}

	private QuickAction initOptionsDropDown(Menu menu) {
		QuickAction optionsDropDown = new QuickAction(this,
				QuickAction.VERTICAL);

		final ArrayList<MenuItem> menuItems = new ArrayList<MenuItem>();

		for (int i = 0; i < menu.size(); i++) {

			MenuItem mItem = menu.getItem(i);
			boolean visible = mItem.isEnabled() && mItem.isVisible();

			if (visible) {

				String name = mItem.getTitle().toString();
				Drawable drawable = mItem.getIcon();

				ActionItem item = new ActionItem(0, name, drawable);
				menuItems.add(mItem);
				optionsDropDown.addActionItem(item);
			}
		}

		optionsDropDown
				.setOnActionItemClickListener(new OnActionItemClickListener() {
					@Override
					public void onItemClick(QuickAction source, int pos,
							int actionId) {
						onOptionsItemSelected(menuItems.get(pos));
					}
				});

		return optionsDropDown;
	}

	public abstract boolean hasOptionsMenu();

	protected final void initFooter(LinearLayout parent) {
		final Activity self = this;
		ImageButton newEntry = new ImageButton(this);
		newEntry.setBackgroundDrawable(getResources().getDrawable(
				R.drawable.btn_default));
		newEntry.setLayoutParams(new LinearLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
		newEntry.setImageResource(R.drawable.androidadd);
		newEntry.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				startActivityForResult(new Intent(getApplicationContext(),
						NewEntry.class), Constants.REQUEST_NEW_ITEM);
			}
		});

		ImageButton search = new ImageButton(this);
		search.setBackgroundDrawable(getResources().getDrawable(
				R.drawable.btn_default));
		search.setLayoutParams(new LinearLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
		search.setImageResource(R.drawable.androidsearch);
		search.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				onKeyDown(KeyEvent.KEYCODE_SEARCH, new KeyEvent(
						KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SEARCH));
			}
		});

		ImageButton more = new ImageButton(this);
		more.setBackgroundDrawable(getResources().getDrawable(
				R.drawable.btn_default));
		more.setLayoutParams(new LinearLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
		more.setImageResource(R.drawable.androidmore);
		more.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (!v.showContextMenu())
					startActivityForResult(new Intent(getApplicationContext(),
							Selection.class), Constants.REQUEST_OVERVIEW);
				else {
					closeContextMenu();
				}
			}
		});
		more.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
			@Override
			public void onCreateContextMenu(ContextMenu m, View v,
					ContextMenuInfo i) {
				showNavigation(self, m);
				showOptions(v, m);
			}

		});

		ImageButton options = new ImageButton(this);
		options.setBackgroundDrawable(getResources().getDrawable(
				R.drawable.btn_default));
		options.setLayoutParams(new LinearLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
		options.setImageResource(android.R.drawable.ic_menu_preferences);
		options.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO options
			}
		});

		parent.addView(newEntry);
		parent.addView(search);
		parent.addView(more);
		// parent.addView(options);

	}

	protected void onNavEntryClicked(Button b) {
	}

	protected final void setNavEntry(String which) {
		if (navButtons != null) {
			for (int i = 0; i < navButtons.getChildCount(); i++) {
				if (((Button) navButtons.getChildAt(i)).getText().toString()
						.equals(which)) {
					switchNavBarTo(i);
					return;
				}
			}
			if (!headText.getText().toString().equals(which))
				addNavItem(which);
		}
	}

	protected void switchNavBarTo(int childId) {
		if (navButtons != null) {
			if (navButtons.getChildCount() > childId) {
				headText.setText(((Button) navButtons.getChildAt(childId))
						.getText().toString());
				for (int i = navButtons.getChildCount() - 1; i >= childId; i--) {
					navButtons.removeViewAt(i);
				}
			}
		}
	}

	protected void showNavigation(final Activity wycActivity, Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.layout.menu_contextmenu, menu);

		MenuItem month = menu.findItem(R.id.menu_month);
		MenuItem time = menu.findItem(R.id.menu_time);
		MenuItem cat = menu.findItem(R.id.menu_cat);
		MenuItem xml = menu.findItem(R.id.menu_xml);

		if (wycActivity instanceof Main)
			month.setEnabled(false);
		if (wycActivity instanceof Overview)
			time.setEnabled(false);
		if (wycActivity instanceof Categories)
			cat.setEnabled(false);
		if (wycActivity instanceof XmlActivity)
			xml.setEnabled(false);

	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_month:
			finish();
			startActivity(new Intent(getApplicationContext(), Main.class));
			break;
		case R.id.menu_time:
			finish();
			startActivity(new Intent(getApplicationContext(), Overview.class));
			break;
		case R.id.menu_cat:
			finish();
			startActivity(new Intent(getApplicationContext(), Categories.class));
			break;
		case R.id.menu_xml:
			finish();
			startActivity(new Intent(getApplicationContext(), XmlActivity.class));
			break;
		case R.id.menu_facebook:
			startFacebook();
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void startFacebook() {
		try {
			/*
			 * Intent intent = new Intent(Intent.ACTION_VIEW);
			 * intent.setClassName("com.facebook.katana",
			 * "com.facebook.katana.ProfileTabHostActivity");
			 * intent.putExtra("extra_user_id", new Long("watchyourcash"));
			 */
			Intent intent = new Intent(Intent.ACTION_VIEW,
					Uri.parse("fb://profile/371332252901632"));
			this.startActivity(intent);
		} catch (Exception e) {
			String url = "https://www.facebook.com/watchyourcash";
			Intent i = new Intent(Intent.ACTION_VIEW);
			i.setData(Uri.parse(url));
			startActivity(i);
		}
	}

	protected final void addNavItem(String name) {
		if (navButtons != null) {
			if (!headText.getText().toString().equals("")) {
				Button button = new Button(this);
				button.setText(headText.getText());
				button.setBackgroundDrawable(getResources().getDrawable(
						R.drawable.btn_header));
				Drawable img = getResources().getDrawable(R.drawable.icon);
				int size = button.getHeight();
				img.setBounds(0, 0, size, size);
				button.setCompoundDrawables(img, null, null, null);
				button.setOnClickListener(new android.view.View.OnClickListener() {
					@Override
					public void onClick(View v) {
						if (v instanceof Button) {
							onNavEntryClicked((Button) v);
							setNavEntry(((Button) v).getText().toString());
						}
					}
				});
				navButtons.addView(button);
			}
			headText.setText(name);
		}
	}

	private void invalidateDiagram() {
		if (diagram == null)
			return;
		if (showDiagram && diagramButton.isEnabled()
				|| diagramButton.getVisibility() == View.GONE) {
			diagram.setVisibility(View.VISIBLE);
			Drawable img = getResources().getDrawable(R.drawable.btn_extended);
			if (horizontalDiagramLayout != null) {
				horizontalDiagramLayout
						.setLayoutParams(new LinearLayout.LayoutParams(
								LayoutParams.FILL_PARENT,
								LayoutParams.FILL_PARENT, 1f));
				img = getResources().getDrawable(R.drawable.btn_collapsed);
				slideInFromRight(horizontalDiagramLayout, 250);
			} else {
				slideInFromTop(diagram, 250);
			}
			img.setBounds(0, 0, img.getIntrinsicWidth(),
					img.getIntrinsicHeight());
			diagramButton.setCompoundDrawables(img, null, null, null);
		} else {
			diagram.setVisibility(View.GONE);
			Drawable img = getResources().getDrawable(R.drawable.btn_collapsed);
			if (horizontalDiagramLayout != null) {
				horizontalDiagramLayout
						.setLayoutParams(new LinearLayout.LayoutParams(
								LayoutParams.FILL_PARENT,
								LayoutParams.FILL_PARENT, 9f));
				img = getResources().getDrawable(R.drawable.btn_left);
			}
			img.setBounds(0, 0, img.getIntrinsicWidth(),
					img.getIntrinsicHeight());
			diagramButton.setCompoundDrawables(img, null, null, null);
		}
		diagram.invalidate();
	}

	protected final void initHeader(ListView l) {
		this.list = l;
		LinearLayout header = new LinearLayout(this);
		header.setOrientation(LinearLayout.VERTICAL);
		diagramButton = new Button(this);
		diagramButton.setText(getString(R.string.diagram));

		header.addView(diagramButton);
		diagram = new Diagram(this) {
			@Override
			public void onItemClicked(int pos) {
				try {
					list.performItemClick(null, pos + 1, 0);// +1 because of the
															// header
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		diagram.setVisibility(View.GONE);

		Drawable img = getResources().getDrawable(R.drawable.collapsed);
		img.setBounds(0, 0, img.getIntrinsicWidth(), img.getIntrinsicHeight());
		diagramButton.setCompoundDrawables(img, null, null, null);
		diagramButton.setBackgroundDrawable(getResources().getDrawable(
				R.drawable.btn_default));

		diagramButton
				.setOnClickListener(new android.view.View.OnClickListener() {

					public void onClick(View view) {
						if (isDiagramShown()) {
							setDiagram(false);
						} else {
							setDiagram(true);
						}
					}

				});
		header.addView(diagram);
		list.addHeaderView(header);
		list.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View arg0, MotionEvent arg1) {
				diagram.onExternalTouch(arg1);
				return false;
			}
		});

		LinearLayout layout = new LinearLayout(this);
		initAdView();

		l.addFooterView(layout);
	}

	protected final void initHeader(ListView l, LinearLayout parent) {
		this.list = l;
		View header = new View(this);
		diagramButton = new Button(this);
		diagramButton.setLayoutParams(new LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT));

		diagram = new Diagram(this) {
			@Override
			public void onItemClicked(int pos) {
				try {
					list.performItemClick(null, pos + 1, 0);// +1 because of the
															// header
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		if (getWindowManager().getDefaultDisplay().getWidth() <= SCREEN_LIMIT)
			diagram.setVisibility(View.GONE);

		Drawable img = getResources().getDrawable(R.drawable.collapsed);
		img.setBounds(0, 0, img.getIntrinsicWidth(), img.getIntrinsicHeight());
		diagramButton.setCompoundDrawables(img, null, null, null);
		diagramButton.setBackgroundDrawable(getResources().getDrawable(
				R.drawable.btn_default));

		diagramButton
				.setOnClickListener(new android.view.View.OnClickListener() {

					public void onClick(View view) {
						if (isDiagramShown()) {
							setDiagram(false);
						} else {
							setDiagram(true);
						}
					}

				});

		horizontalDiagramLayout = new LinearLayout(this);
		horizontalDiagramLayout.setOrientation(LinearLayout.HORIZONTAL);
		horizontalDiagramLayout.setGravity(Gravity.CENTER);
		horizontalDiagramLayout.setLayoutParams(new LinearLayout.LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 1f));

		if (getWindowManager().getDefaultDisplay().getWidth() > SCREEN_LIMIT)
			diagramButton.setVisibility(View.GONE);

		horizontalDiagramLayout.addView(diagramButton);
		horizontalDiagramLayout.addView(diagram);

		parent.addView(horizontalDiagramLayout);

		list.addHeaderView(header);

		LinearLayout layout = new LinearLayout(this);
		initAdView();

		l.addFooterView(layout);
	}

	private LinearLayout createLeftNavigation(final Activity wycActivity) {

		View slideHolder = wycActivity.findViewById(R.id.slideholder);
		if (slideHolder != null) {
			leftNavigation = (SlideHolder) slideHolder;
		}

		LinearLayout content = new LinearLayout(this);

		LayoutInflater inflater = getLayoutInflater();
		inflater.inflate(R.layout.layout_leftnavigation, content);

		Button title = (Button) content.findViewById(R.id.btn_wyc);
		Button month = (Button) content.findViewById(R.id.btn_month);
		Button time = (Button) content.findViewById(R.id.btn_time);
		Button cat = (Button) content.findViewById(R.id.btn_cat);
		Button xml = (Button) content.findViewById(R.id.btn_xml);
		Button feedback = (Button) content.findViewById(R.id.btn_feedback);
		// Button close = (Button)leftNavigation.findViewById(R.id.btn_close);

		if (wycActivity instanceof Main)
			month.setBackgroundDrawable(getResources().getDrawable(
					R.drawable.btnnav));
		if (wycActivity instanceof Overview)
			time.setBackgroundResource(R.drawable.btnnav);
		if (wycActivity instanceof Categories)
			cat.setBackgroundResource(R.drawable.btnnav);
		if (wycActivity instanceof XmlActivity)
			xml.setBackgroundResource(R.drawable.btnnav);

		title.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				toggleLeftNavigation();
			}
		});
		month.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
				startActivity(new Intent(getApplicationContext(), Main.class));
			}
		});
		time.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
				startActivity(new Intent(getApplicationContext(),
						Overview.class));
			}
		});
		cat.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
				startActivity(new Intent(getApplicationContext(),
						Categories.class));
			}
		});
		xml.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
				startActivity(new Intent(getApplicationContext(),
						XmlActivity.class));
			}
		});
		feedback.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				startFacebook();
			}
		});

		return content;
	}

	/**
	 * opens ans closes the diagram if it exists
	 * 
	 * @param open
	 *            true opens it false closes it
	 */
	protected final void setDiagram(boolean open) {
		showDiagram = open;
		invalidateDiagram();
	}

	protected final boolean isDiagramShown() {
		return showDiagram;
	}

	protected final void notifyHeader() {
		if (list.getAdapter() instanceof BasicAdapter)
			diagram.setItems(((BasicAdapter) list.getAdapter()).getItems());
		else if (list.getAdapter() instanceof WrapperListAdapter)
			diagram.setItems(((BasicAdapter) ((WrapperListAdapter) list
					.getAdapter()).getWrappedAdapter()).getItems());
		invalidateDiagram();
		if (diagram.getItems().size() < 2) {
			setHeaderEnabled(false);
		} else {
			setHeaderEnabled(true);
		}
	}

	protected final void setHeaderEnabled(boolean enabled) {
		if (enabled) {
			diagramButton.setEnabled(true);
		} else {
			diagramButton.setEnabled(false);
			setDiagram(false);
			invalidateDiagram();
		}
	}

	private void toggleLeftNavigation() {
		if (leftNavigation != null) {
			leftNavigation.toggle();
		}
	}

	public boolean onCreatePopupMenu(Menu menu) {
		return menu!=null;
	}
	
}
